package com.emip.servlet.report;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.emip.bean.ExpFlagBean;
import com.emip.bean.SiteItemBean;
import com.emip.pojo.Report;
import com.emip.service.ExpFlagService;
import com.emip.service.SiteItemService;
import com.emip.util.ReportFormat;
import com.emip.util.Util;
import com.emip.util.report.Comput;
import com.emip.util.report.Statistics;
import com.emip.util.report.impl.AverageComput;
import com.emip.util.report.impl.MaxComput;
import com.emip.util.report.impl.MinComput;
import com.emip.view.ReportExcelView;
import com.emip.view.ReportPdfView;


public class ReportAction {

	@Autowired
	protected ReportExcelView excelView;
	
	@Autowired
	protected ReportPdfView pdfView;
	
	@Autowired
	protected SiteItemService siteItemService;
	
	@Autowired
	protected ExpFlagService expFlagService;
	
	protected ModelMap mmap = new ModelMap();
	
	private ReportFormat reportFormat;
	
	private List<Comput> computs;
	private Statistics statics;
	private String curName;
	
	public String getCurName() {
		if (curName == null) {
			curName = this.getClass().getSimpleName();
			curName = curName.substring(0, curName.indexOf("ReportAction"));
		}
		return curName;
	}
	
	protected ModelMap setDefaultParams(ModelMap mmap) {
		if (mmap == null) mmap = new ModelMap();
		mmap.put("type", getCurName().toLowerCase());
		
		List<ExpFlagBean> flags = expFlagService.getAll();
		Map<String, ExpFlagBean> flagMap = new HashMap<String, ExpFlagBean>();
		for (int i = 0; i < flags.size(); i++) {
			ExpFlagBean flag = flags.get(i);
			flagMap.put(Util.trim(flag.getFlag()), flag);
		}
        
		mmap.put("flags", Util.Object2String(flagMap));
		return mmap;
	}
	
	protected <T> Report formatReportBody(List<T> datas) {
		ReportFormat reportFormat = new ReportFormat();
		reportFormat.appendBodyData(datas);
		
		return reportFormat.getReport();
	}
	
	protected <T> Report formatReport(List<T> datas, int[] siteItemIds, HttpSession session) {
		prepareComput();
		reportFormat = new ReportFormat();
		List<ExpFlagBean> flags = expFlagService.getAll();
		List<SiteItemBean> siteItems = new ArrayList<SiteItemBean>();
		for (int i = 0; i < siteItemIds.length; i++) {
			SiteItemBean siteItem = siteItemService.getSiteItemByID(siteItemIds[i]);
			siteItems.add(siteItem);
			List<SiteItemBean> temp = new ArrayList<SiteItemBean>();
			temp.add(siteItem);
			statics = new Statistics(computs, temp, flags);
			statics.comput(datas);
			reportFormat.appendFooterData(statics.getResults());
			session.setAttribute(getCurName()+"ReportProgress", 100*i/(siteItemIds.length+1));
		}
		
		reportFormat.appendBodyData(datas);
		
		
		List<String> colNames = new ArrayList<String>();
		List<String> indexes = new ArrayList<String>();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			colNames.add(siteItem.getItem().getName());
			indexes.add(siteItem.getItem().getId());
		}
		reportFormat.setColNames(colNames);
		reportFormat.setIndexes(indexes);
		Report report = reportFormat.getReport();
		session.setAttribute(getCurName()+"Report", report);
		session.setAttribute(getCurName()+"ReportProgress", 100);
		return report;
	}
	
	protected <T> Report formatReport(Map<String, Object[]> stats, List<SiteItemBean> siteItems, HttpSession session) {
		prepareComput();
		reportFormat = new ReportFormat();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			String siteId = siteItem.getSite().getId();
			String itemId = siteItem.getItem().getId();
			reportFormat.appendFooterData((String) stats.get(siteId + "_" + itemId), siteId, itemId);
		}
		
		List<String> colNames = new ArrayList<String>();
		List<String> indexes = new ArrayList<String>();
		for (int i = 0; i < siteItems.size(); i++) {
			SiteItemBean siteItem = siteItems.get(i);
			colNames.add(siteItem.getItem().getName());
			indexes.add(siteItem.getItem().getId());
		}
		reportFormat.setColNames(colNames);
		reportFormat.setIndexes(indexes);
		Report report = reportFormat.getReport();
		session.setAttribute(getCurName()+"Report", report);
		session.setAttribute(getCurName()+"ReportProgress", 100);
		return report;
	}
	
	public void prepareComput() {
		this.computs = new ArrayList<Comput>();
		this.computs.add(new MaxComput());
		this.computs.add(new MinComput());
		this.computs.add(new AverageComput());
		//超标率
		//水质评定
	}
	
	@RequestMapping(value="/report.xls", method=RequestMethod.GET)
	public ModelAndView getExcel(HttpSession session) {
		Report report = (Report) session.getAttribute(getCurName() + "Report");
		if (report != null) {
			Map<String, Object> attributes = new HashMap<String, Object>();
			attributes.put("report", report);
			excelView.setAttributesMap(attributes);
		}
		return new ModelAndView(excelView);
	}
	
	@RequestMapping(value="/report.pdf", method=RequestMethod.GET)
	public ModelAndView getPdf(HttpSession session) {
		Report report = (Report) session.getAttribute(getCurName() + "Report");
		if (report != null) {
			Map<String, Object> attributes = new HashMap<String, Object>();
			attributes.put("report", report);
			pdfView.setAttributesMap(attributes);
		}
		return new ModelAndView(pdfView);
	}
	
	@RequestMapping(value="/data/progress", method=RequestMethod.GET)
	@ResponseBody
	public Map<String, Integer> getProgress(HttpSession session) {
		Integer progress = (Integer) session.getAttribute(getCurName() + "ReportProgress");
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("progress", progress);
		return map;
	}
	
}
